package mspbots.data.tl.prod.autotask.service.impl;


import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.data.tl.base.AbstractBaseServiceImpl;
import mspbots.data.tl.entity.ResultEntity;
import mspbots.data.tl.prod.autotask.mapper.TaskAutoProjectMapper;
import mspbots.data.tl.prod.autotask.mapper.TaskAutotaskInformationMapper;
import mspbots.data.tl.prod.autotask.model.TaskAutotaskCompany;
import mspbots.data.tl.prod.autotask.model.TaskAutotaskContact;
import mspbots.data.tl.prod.autotask.model.TaskAutotaskInformation;
import mspbots.data.tl.prod.autotask.model.TaskAutotaskProject;
import mspbots.data.tl.prod.autotask.service.TaskAutotaskProjectService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Log4j2
@RequiredArgsConstructor
@DS("master")
public class TaskAutotaskProjectServiceImpl extends AbstractBaseServiceImpl<TaskAutoProjectMapper, TaskAutotaskProject>
        implements TaskAutotaskProjectService {

    private final TaskAutoProjectMapper taskAutoProjectMapper;

    private final TaskAutotaskInformationMapper informationMapper;

    @Override
    public void sync(ResultEntity content) {


        log.debug("Auto task project receiver content {}", content);
        JsonNode entity = content.getEntity();
        TaskAutotaskProject data = TaskAutotaskProject.builder()
                .projectId(super.getLongValue(entity.get("id")))
                .actualBilledHours(ObjectUtils.isEmpty(entity.get("actualBilledHours")) ? null : entity.get("actualBilledHours").asDouble())
                .actualHours(ObjectUtils.isEmpty(entity.get("actualHours")) ? null : entity.get("actualHours").asDouble())
                .changeOrdersBudget(ObjectUtils.isEmpty(entity.get("changeOrdersBudget")) ? null : entity.get("changeOrdersBudget").asDouble())
                .changeOrdersRevenue(ObjectUtils.isEmpty(entity.get("changeOrdersRevenue")) ? null : entity.get("changeOrdersRevenue").asDouble())
                .completedDateTime(ObjectUtils.isEmpty(entity.get("completedDateTime")) || "null".equalsIgnoreCase(entity.get("completedDateTime").asText())? null : LocalDateTime.parse(entity.get("completedDateTime").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .completedPercentage(ObjectUtils.isEmpty(entity.get("completedPercentage")) ? null : entity.get("completedPercentage").asDouble())
                .contractId(ObjectUtils.isEmpty(entity.get("contractID")) ? null : entity.get("contractID").asLong())
                .createDateTime(ObjectUtils.isEmpty(entity.get("createDateTime")) ? null : LocalDateTime.parse(entity.get("createDateTime").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .department(ObjectUtils.isEmpty(entity.get("department")) ? null : entity.get("department").asText())
                .description(ObjectUtils.isEmpty(entity.get("description")) ? null : entity.get("description").asText())
                .duration(ObjectUtils.isEmpty(entity.get("duration")) ? null : entity.get("duration").asLong())
                .endDateTime(ObjectUtils.isEmpty(entity.get("endDateTime")) ? null : LocalDateTime.parse(entity.get("endDateTime").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .estimatedSalesCost(ObjectUtils.isEmpty(entity.get("estimatedSalesCost")) ? null : entity.get("estimatedSalesCost").asDouble())
                .estimatedTime(ObjectUtils.isEmpty(entity.get("estimatedTime")) ? null : entity.get("estimatedTime").asLong())
                .extProjectType(ObjectUtils.isEmpty(entity.get("extProjectType")) ? null : entity.get("extProjectType").asText())
                .extProjectNumber(ObjectUtils.isEmpty(entity.get("extProjectNumber")) ? null : entity.get("extProjectNumber").asText())
                .laborEstimatedCosts(ObjectUtils.isEmpty(entity.get("laborEstimatedCosts")) ? null : entity.get("laborEstimatedCosts").asLong())
                .laborEstimatedMarginPercentage(ObjectUtils.isEmpty(entity.get("laborEstimatedMarginPercentage")) ? null : entity.get("laborEstimatedMarginPercentage").asLong())
                .laborEstimatedRevenue(ObjectUtils.isEmpty(entity.get("laborEstimatedRevenue")) ? null : entity.get("laborEstimatedRevenue").asLong())
                .originalEstimatedRevenue(ObjectUtils.isEmpty(entity.get("originalEstimatedRevenue")) ? null : entity.get("originalEstimatedRevenue").asLong())
                .projectCostEstimatedMarginPercentage(ObjectUtils.isEmpty(entity.get("projectCostEstimatedMarginPercentage")) ? null : entity.get("projectCostEstimatedMarginPercentage").asLong())
                .projectCostsBudget(ObjectUtils.isEmpty(entity.get("projectCostsBudget")) ? null : entity.get("projectCostsBudget").asLong())
                .projectCostsRevenue(ObjectUtils.isEmpty(entity.get("projectCostsRevenue")) ? null : entity.get("projectCostsRevenue").asLong())
                .projectLeadResourceId(ObjectUtils.isEmpty(entity.get("projectLeadResourceID")) ? null : entity.get("projectLeadResourceID").asInt())
                .projectName(ObjectUtils.isEmpty(entity.get("projectName")) ? null : entity.get("projectName").asText())
                .projectNumber(ObjectUtils.isEmpty(entity.get("projectNumber")) ? null : entity.get("projectNumber").asText())
                .purchaseOrderNumber(ObjectUtils.isEmpty(entity.get("purchaseOrderNumber")) ? null : entity.get("purchaseOrderNumber").asText())
                .sgda(ObjectUtils.isEmpty(entity.get("sgda")) ? null : entity.get("sgda").asLong())
                .status(ObjectUtils.isEmpty(entity.get("status")) ? null : entity.get("status").asLong())
                .startDateTime(ObjectUtils.isEmpty(entity.get("startDateTime")) ? null : LocalDateTime.parse(entity.get("startDateTime").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .statusDetail(ObjectUtils.isEmpty(entity.get("statusDetail")) ? null : entity.get("statusDetail").asText())
                .statusDateTime(ObjectUtils.isEmpty(entity.get("statusDateTime")) ? null : LocalDateTime.parse(entity.get("statusDateTime").textValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME))
                .projectType(ObjectUtils.isEmpty(entity.get("projectType")) ? null : entity.get("projectType").asText())
                .syncTime(LocalDateTime.now())
                .build();

        data.setTenantCode(content.getTenantId());


        List<TaskAutotaskInformation> informationList = this.informationMapper.selectList(Wrappers.<TaskAutotaskInformation>lambdaQuery()
                .eq(TaskAutotaskInformation::getTenantCode, data.getTenantCode())
                .eq(TaskAutotaskInformation::getType,"Projects")
                .in(TaskAutotaskInformation::getName, List.of("Status","ProjectType")));


        TaskAutotaskInformation  statusInformation = informationList.stream()
                .filter(infor -> Long.parseLong(infor.getValue()) == entity.get("status").asLong() && infor.getName().equals("Status"))
                .findFirst()
                .orElse(null);


        TaskAutotaskInformation  projectTypeInformation = informationList.stream()
                .filter(infor -> Long.parseLong(infor.getValue()) == entity.get("status").asLong() && infor.getName().equals("ProjectType"))
                .findFirst()
                .orElse(null);

        data.setStatusName(ObjectUtils.isEmpty(statusInformation)? null:statusInformation.getLabel());
        data.setProjectTypeName(ObjectUtils.isEmpty(projectTypeInformation)? null:projectTypeInformation.getLabel());

        

        TaskAutotaskProject dbData = super.baseMapper.selectOne(Wrappers.<TaskAutotaskProject>lambdaQuery()
                .eq(TaskAutotaskProject::getTenantCode, data.getTenantCode())
                .eq(TaskAutotaskProject::getProjectId, data.getProjectId())
                .last("limit 1"));
        if (ObjectUtils.isEmpty(dbData)) {
            super.baseMapper.insert(data);
        } else {
            data.setId(dbData.getId());
            super.baseMapper.updateById(data);
        }


    }
}
